/**
 * This file is part of the CAKIS project.
 * 
 * Copyright (c) 2009-2010 - Florian Arndt, Christian Kerl
 * 
 * @license GNU Lesser General Public License v3 <http://www.opensource.org/licenses/lgpl-3.0.html>
 * @since   11.04.2010
 * @version SVN: $Id: ProductServiceImpl.java 136 2010-05-15 10:36:43Z christian-kerl@web.de $
 */
package org.cakis.server.service.impl;

import java.util.List;

import javax.ejb.Stateless;

import org.cakis.server.Names;
import org.cakis.server.model.Product;
import org.cakis.server.model.StockUnit;
import org.cakis.server.model.repository.ProductRepository;
import org.cakis.server.model.repository.StockUnitRepository;
import org.cakis.server.service.ProductNotFoundException;
import org.cakis.server.service.ProductService;
import org.cakis.server.service.StockUnitNotFoundException;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;

/**
 * ProductServiceImpl
 *
 * @author Christian Kerl
 */
@Stateless
@Name(Names.ProductService)
@Scope(ScopeType.APPLICATION)
@Startup
public class ProductServiceImpl implements ProductService.Local {
    private ProductRepository productRepository;
    private StockUnitRepository stockUnitRepository;

    private StockUnitCleaner stockUnitCleaner;

    private ProductLookupServiceRegistryImpl productLookupRegistry;

    @In(Names.ProductRepository)
    public void setProductRepository(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    @In(Names.StockUnitRepository)
    public void setStockUnitRepository(StockUnitRepository stockUnitRepository) {
        this.stockUnitRepository = stockUnitRepository;
        this.stockUnitCleaner = new StockUnitCleaner(stockUnitRepository);
    }

    @In(Names.ProductLookupServiceRegistry)
    public void setProductLookupRegistry(ProductLookupServiceRegistryImpl productLookupRegistry) {
        this.productLookupRegistry = productLookupRegistry;
    }

    @Override
    public Product addProduct(Product product) throws IllegalArgumentException, StockUnitNotFoundException {
        if(product == null || product.getStandardQuantity() == null) {
            throw new IllegalArgumentException();
        }

        // improve validation
        if(product.getName() == null || product.getEanNumber() == null) {
            throw new IllegalArgumentException();
        }

        Product cleanProduct = new Product();
        cleanProduct.setName(product.getName());
        cleanProduct.setEanNumber(product.getEanNumber());
        cleanProduct.getStandardQuantity().setNumberOfPieces(product.getStandardQuantity().getNumberOfPieces());
        cleanProduct.getStandardQuantity().setQuantity(product.getStandardQuantity().getQuantity());
        cleanProduct.getStandardQuantity().setUnit(stockUnitCleaner.getCleanStockUnit(product.getStandardQuantity().getUnit()));

        productRepository.store(cleanProduct);

        return cleanProduct;
    }

    @Override
    public Product getProduct(Long id) throws ProductNotFoundException {
        Product result = productRepository.findById(id);

        if(result == null) {
            throw new ProductNotFoundException(id.toString());
        }

        return result;
    }

    @Override
    public Product getProduct(String ean) throws ProductNotFoundException, StockUnitNotFoundException {
        Product result = productRepository.findByEanNumber(ean);

        if(result == null) {
            result = productLookupRegistry.getProductInformation(ean);

            if(result != null) {
                result.getStandardQuantity().setUnit(stockUnitCleaner.getCleanStockUnit(result.getStandardQuantity().getUnit()));
            }
        }

        if(result == null) {
            throw new ProductNotFoundException(ean);
        }

        return result;
    }

    @Override
    public List<StockUnit> getAllStockUnits() {
        return stockUnitRepository.findAll();
    }
}
